﻿namespace Stopwatch
{
    using Microsoft.Phone.Controls;
    using Stopwatch.Controls;
    using Stopwatch.Core;
    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Windows;
    using System.Windows.Controls;

    public partial class MainPage : PhoneApplicationPage
    {
        StopWatch stopWatch;
        StopTimer stopTimer;
        StopedItemModel stopListItems;

        App app;

        // 构造函数
        public MainPage()
        {
            app = Application.Current as App;
            InitializeComponent();
            stopListItems = new StopedItemModel();

            // 将 listbox 控件的数据上下文设置为示例数据
            stoplist.SizeChanged += stoplistSizeChanged;

            InitializeCoreData();
        }

        private void InitializeCoreData()
        {
            stoplist.ItemsSource = stopListItems;

            if (app.State.WatchAddedList == null || app.State.WatchAddedList.Length == 0)
            {
                stopwatchControl.SubEnabled = false;
            }
            else
            {
                for (int i = 0; i < app.State.WatchAddedList.Length; i++)
                {
                    var s = new StopedItem(app.State.WatchAddedList[i]);
                    s.OriginalTime = app.State.WatchAddedList2[i].ToWatch();
                    stopListItems.Add(s);
                }

                stopwatchControl.SubEnabled = true;
            }

            if (app.State.WatchState != null)
            {
                var s = app.State.WatchState;
                stopWatch = new StopWatch(s);
                stopWatch.Tick += stopWatchOnTick;
                if (s.Status == Status.Started)
                {
                    StopwatchStart.Visibility = System.Windows.Visibility.Collapsed;
                    StopwatchPause.Visibility = System.Windows.Visibility.Visible;
                    StopwatchAdd.IsEnabled = true;
                }
                else if (s.Status == Status.Paused)
                {
                    stopWatchOnTick(stopWatch, EventArgs.Empty);
                }

                StopwatchReset.IsEnabled = true;
            }
        }

        private void stoplistSizeChanged(object sender, SizeChangedEventArgs e)
        {
            if (e.NewSize.Height > StopedItemScrollViewer.Height)
            {
                StopedItemScrollViewer.ScrollToVerticalOffset(e.NewSize.Height - StopedItemScrollViewer.Height);
            }
        }

        private void PhoneApplicationPage_OrientationChanged(object sender, OrientationChangedEventArgs e)
        {            
        }

        private void TimerStartOnClick(object sender, RoutedEventArgs e)
        {
            if (timerControl.Hour == 0 && timerControl.Minute == 0 && timerControl.Second == 0)
            {
                return;
            }

            if (stopTimer == null)
            {
                stopTimer = new StopTimer(timerControl.Hour, timerControl.Minute, timerControl.Second);
                stopTimer.Tick += stopTimerOnTick;
                stopTimer.Stoped += stopTimerOnStoped;
                timerControl.Mode = Mode.Show;
            }

            if (stopTimer.Status == Status.Started)
            {
                stopTimer.Pause();
                timerPause.Visibility = System.Windows.Visibility.Collapsed;
                timerStart.Visibility = System.Windows.Visibility.Visible;
            }
            else
            {
                stopTimer.Start();
                timerStart.Visibility = System.Windows.Visibility.Collapsed;
                timerPause.Visibility = System.Windows.Visibility.Visible;
            }

            timerReset.IsEnabled = true;
        }

        private void TimerResetOnClick(object sender, RoutedEventArgs e)
        {
            timerReset.IsEnabled = false;
            timerPause.Visibility = System.Windows.Visibility.Collapsed;
            timerStart.Visibility = System.Windows.Visibility.Visible;

            timerControl.Reset();

            stopTimer.Reset();
            stopTimer = null;
        }

        private void StopwatchStartOnClick(object sender, RoutedEventArgs e)
        {
            if (stopWatch == null)
            {
                stopWatch = new StopWatch();
                stopWatch.Tick += stopWatchOnTick;

                // reset WatchAddedList
                app.State.WatchAddedList = new Time[0];
                app.State.WatchAddedList2 = new Time[0];
            }

            var start = sender as Button;

            if (stopWatch.Status == Status.Started)
            {
                stopWatch.Pause();
                StopwatchPause.Visibility = System.Windows.Visibility.Collapsed;
                StopwatchStart.Visibility = System.Windows.Visibility.Visible;
                this.StopwatchAdd.IsEnabled = false;

                stopwatchControl.IsShowPauseTag = true;
            }
            else
            {
                stopWatch.Start();
                StopwatchStart.Visibility = System.Windows.Visibility.Collapsed;
                StopwatchPause.Visibility = System.Windows.Visibility.Visible;
                this.StopwatchAdd.IsEnabled = true;

                stopwatchControl.IsShowPauseTag = false;
            }

            this.StopwatchReset.IsEnabled = true;

            // update state
            if (app.State.WatchState == null)
            {
                app.State.WatchState = new WatchState();
            }

            app.State.WatchState.StartTime = stopWatch.StartTime;
            app.State.WatchState.PauseTime = stopWatch.PauseTime;
            app.State.WatchState.Status = stopWatch.Status;
        }

        private void StopwatchResetOnClick(object sender, RoutedEventArgs e)
        {
            stopWatch.Stop();
            stopListItems.Clear();

            stopwatchControl.SubEnabled = false;
            stopwatchControl.Hours = 0;
            stopwatchControl.Minutes = 0;
            stopwatchControl.Seconds = 0;
            stopwatchControl.Milliseconds = 0;

            stopWatch.Dispose();
            stopWatch = null;

            this.StopwatchReset.IsEnabled = false;
            this.StopwatchAdd.IsEnabled = false;
            StopwatchPause.Visibility = System.Windows.Visibility.Collapsed;
            StopwatchStart.Visibility = System.Windows.Visibility.Visible;

            stopwatchControl.IsShowPauseTag = false;
        }

        private void StopwatchAddOnClick(object sender, RoutedEventArgs e)
        {
            var time = stopWatch.AddStopTime();
            var oTime = stopWatch.Main;
            var s = new StopedItem(time);
            s.OriginalTime = oTime.ToWatch();
            stopListItems.Add(s);

            if (app.State.WatchAddedList == null)
            {
                app.State.WatchAddedList = new Time[0];
                app.State.WatchAddedList2 = new Time[0];
            }

            List<Time> times = new List<Time>(app.State.WatchAddedList);
            times.Add(time);
            app.State.WatchAddedList = times.ToArray();
            List<Time> times2 = new List<Time>(app.State.WatchAddedList);
            times2.Add(oTime);
            app.State.WatchAddedList2 = times2.ToArray();

            if (!stopwatchControl.SubEnabled)
            {
                stopwatchControl.SubEnabled = true;
                app.State.WatchState.SubEnabled = true;
            }
            app.State.WatchState.NewTime = stopWatch.NewTime;
        }

        private void stopWatchOnTick(object sender, EventArgs e)
        {
            var watch = sender as StopWatch;
            if (watch != null)
            {
                this.Dispatcher.BeginInvoke(() =>
                {
                    stopwatchControl.Hours = watch.Main.Hours;
                    stopwatchControl.Minutes = watch.Main.Minutes;
                    stopwatchControl.Seconds = watch.Main.Seconds;
                    stopwatchControl.Milliseconds = watch.Main.Milliseconds;

                    if (watch.SubEnabled)
                    {
                        stopwatchControl.SubMinutes = watch.Sub.Minutes;
                        stopwatchControl.SubSeconds = watch.Sub.Seconds;
                        stopwatchControl.SubMilliseconds = watch.Sub.Milliseconds;
                    }
                });
            }
        }

        Time currentTimerTime = new Time();

        private void stopTimerOnTick(object sender, EventArgs e)
        {
            var timer = sender as StopTimer;
            if (timer != null)
            {
                var time = new Time(timer.Hour, timer.Minute, timer.Second);

                if (currentTimerTime != time)
                {
                    currentTimerTime = time;

                    this.Dispatcher.BeginInvoke(() =>
                    {
                        timerControl.Hour = currentTimerTime.Hours;
                        timerControl.Minute = currentTimerTime.Minutes;
                        timerControl.Second = currentTimerTime.Seconds;
                    });
                }
            }
        }

        private void stopTimerOnStoped(object sender, EventArgs e)
        {
            var timer = sender as StopTimer;
            if (timer != null)
            {
                timer.Dispose();
                stopTimer = null;
                this.Dispatcher.BeginInvoke(() =>
                {
                    timerStart.IsEnabled = false;
                    timerStart.Visibility = System.Windows.Visibility.Visible;
                    timerPause.Visibility = System.Windows.Visibility.Collapsed;
                });

                new System.Threading.Timer((s) =>
                {
                    this.Dispatcher.BeginInvoke(() =>
                    {
                        timerReset.IsEnabled = false;
                        timerStart.IsEnabled = true;

                        timerControl.Reset();
                    });
                }, null, 800, Timeout.Infinite);
            }
        }

        private void AboutOnClick(object sender, EventArgs e)
        {
            NavigationService.Navigate(new Uri("/Infomation.xaml", UriKind.Relative));
        }
    }
}